#include "stdafx.h"

Camera::Camera(void)
:cameraStrategyCurrent(0),
 cameraXRotSpeed(0.01f),
 cameraYRotSpeed(0.01f),
 cameraSpeed(0.01f),
 bDirty(false)
{
	matProjection.identity();
	matView.identity();
}

Camera::~Camera(void)
{
}

void Camera::moveLocal(const vec3f& dir)
{
	// convert dir in local space to world space
	vec3f& worldDir = localToWorld(dir);
	// update position
	position += worldDir * cameraSpeed;

	bDirty = true;
}

void Camera::setPosition(const vec3f& pos)
{
	Actor::setPosition(pos);
	bDirty = true;
}

void Camera::pitch(float radius)
{
	radius *= cameraXRotSpeed;
	// rotate around local x-axis
	// convert world space x axis to local space
	//vec3f& xAxisfWorld = localToWorld(xAxisf);
	rotate(xAxisf, radius);

	bDirty = true;
}

void Camera::yaw(float radius)
{
	radius *= cameraYRotSpeed;
	// rotation around world y-axis
	rotate(yAxisf, radius);

	bDirty = true;
}

void Camera::roll(float angle)
{
	// rotate around local z-axis
	rotate(zAxisf, angle);

	bDirty = true;
}

void Camera::update(float dt)
{
	if(cameraStrategyCurrent)
	{
		cameraStrategyCurrent->update(dt);
	}

	if(bDirty)
	{
		// calculate view matrix
		mat4f matRot;
		matView.identity();
		rotation.getMatrix(matRot);
		matRot = matRot.transpose();
		matView.translation(-position);
		matView = matView * matRot;

		bDirty = false;
	}
}

void Camera::setPerspective(float halfAngleInDegree, float ratio, float znear, float zfar)
{
	matProjection = getProjectionMatrixRH(halfAngleInDegree, ratio, znear, zfar);

	// todo calculate frustum
}